public Class ContactAddressTriggerHandler{

static Set<Id> conaddressupdateid=new Set<Id>();
static Set<Id> conaddressinsertid=new Set<Id>();

public void ContactAddressInsert(List<Contact_Address__c> conaddresslist){
     Set<Id> addressid=new Set<Id>();
     Set<Id> accid=new Set<Id>();
    List<Contact_Address__c> oldcontactaddresslist=new List<Contact_Address__c>();
    List<Contact_Address__c> oldcontactaddressupdatelist=new List<Contact_Address__c>();
    Contact_Address__c add=new Contact_Address__c();
    
    if(conaddresslist!=null&&conaddresslist.size()>0){ 
      add= conaddresslist[0];
        for(Contact_Address__c conaddress: conaddresslist){
            addressid.add(conaddress.Id);
            accid.add(conaddress.Contact__c);
        }       
        oldcontactaddresslist=[select Contact__c,Preferred__c from Contact_Address__c where Preferred__c=true AND Contact__c IN:accid AND Id NOT IN:addressid];
        
    for(Contact_Address__c conaddress: conaddresslist){
            
            // To insert country code..
                if(conaddress.Country__c!=null){
                String country=conaddress.Country__c;
                String c1=country.substring((country.indexOf('(')+1),country.indexOf(')'));
                conaddress.Country_Name__c=c1;
                }
            // To insert state code..
                if(conaddress.State__c!=null){
                    String state=conaddress.State__c;
                    String c1=state.substring((state.indexOf('(')+1),state.indexOf(')'));
                    conaddress.State_Name__c=c1;
                }
            system.debug('&&oldcontactaddresslist'+ oldcontactaddresslist);
            system.debug('&&conaddresslist'+ conaddresslist);
            if(oldcontactaddresslist!=null && oldcontactaddresslist.size()>0){                 
                      
                   if(conaddress.Preferred__c==true) {      
                    for(Contact_Address__c oldaddress : oldcontactaddresslist){
                             oldaddress.Preferred__c=false;
                             oldcontactaddressupdatelist.add(oldaddress);
                             conaddressinsertid.add(oldaddress.Id);       
                    }
                  }
                    
            }else{
                add.Preferred__c=true;
            }                             
        }
        
        system.debug('&&oldcontactaddressupdatelist'+ oldcontactaddressupdatelist);
      if(!oldcontactaddressupdatelist.IsEmpty()){
          update oldcontactaddressupdatelist;
      }
    
    }
    
 }
public void ContactAddressUpdate(List<Contact_Address__c> newconaddresslist,List<Contact_Address__c> oldconaddresslist){
     Set<Id> addressid=new Set<Id>();
     Set<Id> accid=new Set<Id>();
    List<Contact_Address__c> oldcontactaddresslist=new List<Contact_Address__c>();
    List<Contact_Address__c> oldcontactaddressupdatelist=new List<Contact_Address__c>();
    
    if(newconaddresslist!=null&&newconaddresslist.size()>0){    
        for(Contact_Address__c conaddress: newconaddresslist){
            addressid.add(conaddress.Id);
            accid.add(conaddress.Contact__c);
        }       
        oldcontactaddresslist=[select Contact__c,Preferred__c from Contact_Address__c where Preferred__c=true AND Contact__c IN:accid AND Id NOT IN:addressid];
        
        
            for(Contact_Address__c newconaddress: newconaddresslist){
                                // To insert country code..
					                if(newconaddress.Country__c!=null){
					                String country=newconaddress.Country__c;
					                String c1=country.substring((country.indexOf('(')+1),country.indexOf(')'));
					                newconaddress.Country_Name__c=c1;
					                }
					            // To insert state code..
					                if(newconaddress.State__c!=null){
					                    String state=newconaddress.State__c;
					                    String c1=state.substring((state.indexOf('(')+1),state.indexOf(')'));
					                    newconaddress.State_Name__c=c1;
					                }
                for(Contact_Address__c oldconaddress: oldconaddresslist){
                    if((newconaddress.Preferred__c==true && oldconaddress.Preferred__c==false && newconaddress.Contact__c==oldconaddress.Contact__c)){ 
                        for(Contact_Address__c accvalue: oldcontactaddresslist){
                              accvalue.Preferred__c=false;        
                              oldcontactaddressupdatelist.add(accvalue);
                              conaddressupdateid.add(accvalue.Id);                            
                          } 
                    } else{
                    for(Contact_Address__c conval: newconaddresslist){
                          
                            if(conaddressupdateid.contains(conval.id) ){
                            	
                            }else{
                            if(conaddressinsertid.IsEmpty()&&(newconaddress.Preferred__c==false&& oldconaddress.Preferred__c==true))
                             trigger.new[0].addError('cannot update');  
                            }
                        }
                    
                    }
                
                }
            }
        }
        
        if(!oldcontactaddressupdatelist.isEmpty()){
                try{
                    
                    update oldcontactaddressupdatelist;
                }catch(Exception e){
                    system.debug('# Exception while updating : '+e);
                }
            }                                  
    }
    public void ContactAddressDelete(List<Contact_Address__c> accountaddresslist){
        if(accountaddresslist!=null&&accountaddresslist.size()>0){
            system.debug('@@accountemaillist '+accountaddresslist);
            for(Contact_Address__c conaddress: accountaddresslist){
            
            if(conaddress.Preferred__c==true){
                    trigger.old[0].addError('Cannot delete prefered record');  
                }
            }
        
        }
    }
/************************************************************************
        Purpose     : Test Class                  
        Parameters  : None
        Returns     : None
***********************************************************************/
    @isTest(SeeAllData=false)
     static public void testContactAddressTriggerHandler() {
         PIMS_Reserved_Id__c pimsid=new PIMS_Reserved_Id__c();
         pimsid.PIMS_Id__c='0000-0000';
         pimsid.Used__c=false;
         insert pimsid;
         
         PIMS_Reserved_Id__c pimsid1=new PIMS_Reserved_Id__c();
         pimsid1.PIMS_Id__c='0001-0000';
         pimsid1.Used__c=false;
         insert pimsid1;
         
         Account acc=new Account();
         acc.Name='test';
         acc.Type='SSO';
         insert acc;
         
         
         Contact con=new Contact();
         con.LastName='Test';
         con.AccountId=acc.id;
         con.Status__c='Active';
         con.Affiliate_Organizational_Role__c='test';
         con.Gender__c='Male';
         insert con;
         
         Contact_Address__c contactaddress=new Contact_Address__c();
         contactaddress.Contact__c=con.id;
         contactaddress.Address_Type__c='Home';
         contactaddress.Country__c='Canada (CA)';
         contactaddress.State__c='Test (TT)';
         contactaddress.Preferred__c=true;
         insert contactaddress;
         update contactaddress;
         
         Contact_Address__c contactaddress0=new Contact_Address__c();
         contactaddress0.Contact__c=con.id;
         contactaddress0.Address_Type__c='Home';
         contactaddress0.Country__c='Canada (CA)';
         contactaddress0.State__c='Test (TT)';
         contactaddress0.Preferred__c=true;
         //insert contactaddress0;
        
         Contact_Address__c contactaddress1=new Contact_Address__c();
         contactaddress1.Contact__c=con.id;
         contactaddress1.Address_Type__c='Home';
         contactaddress1.Country__c='Canada (CA)';
         contactaddress1.State__c='Test (TT)';
         contactaddress1.Preferred__c=false;
         insert contactaddress1;
         contactaddress1.Preferred__c=true;
         update contactaddress1;
         
         Contact_Address__c contactaddress2=new Contact_Address__c();
         contactaddress2.Contact__c=con.id;
         contactaddress2.Address_Type__c='Home';
         contactaddress2.Country__c='Canada (CA)';
         contactaddress2.State__c='Test (TT)';
         contactaddress2.Preferred__c=false;
         insert contactaddress2;
         delete contactaddress2;
         
     }

}